import random
import logging
import string
import time

from django.http import HttpResponse
from django.core.mail import send_mail

from rest_framework.views import APIView
from rest_framework.views import Response
from rest_framework.generics import CreateAPIView, RetrieveUpdateAPIView, UpdateAPIView
from rest_framework import status
from django_redis import get_redis_connection

from geetest import GeetestLib

from . import models
from . import serializers
from luffyapi.settings import contants
from luffyapi.libs.ronglianyun.SendMessage import send_message
from mycelery.sms.tasks import send_sms1


logger = logging.getLogger('django')


class CaptchaApiView(APIView):

    captcha_id = "5e876edb2bda195c265416b70e7389a7"
    private_key = "c1f0f6f5958507924d187db31cd136e5"
    user_id = 'test'
    status = 1

    def get(self, request):
        gt = GeetestLib(self.captcha_id, self.private_key)
        status = gt.pre_process(self.user_id)
        # request.session[gt.GT_STATUS_SESSION_KEY] = status
        # request.session["user_id"] = self.user_id
        response_str = gt.get_response_str()
        return HttpResponse(response_str)

    def post(self, request):
        gt = GeetestLib(self.captcha_id, self.private_key)
        # challenge = request.POST.get(gt.FN_CHALLENGE, '')
        # validate = request.POST.get(gt.FN_VALIDATE, '')
        # seccode = request.POST.get(gt.FN_SECCODE, '')
        # status = request.session[gt.GT_STATUS_SESSION_KEY]
        # user_id = request.session["user_id"]
        challenge = request.data.get(gt.FN_CHALLENGE, '')
        validate = request.data.get(gt.FN_VALIDATE, '')
        seccode = request.data.get(gt.FN_SECCODE, '')
        if self.status:
            result = gt.success_validate(challenge, validate, seccode, self.user_id)
        else:
            result = gt.failback_validate(challenge, validate, seccode)
        result = {"status": "success"} if result else {"status": "fail"}
        return Response(result)


class UserAPIView(CreateAPIView):

    queryset = models.User.objects.all()
    serializer_class = serializers.UserModelSerializer


# 实时监测接口：验证手机号是否存在
class MobileAPIView(APIView):

    def get(self, request, mobile):
        user = models.User.objects.filter(mobile=mobile)
        if user:
            return Response({'msg': '抱歉，该手机号码已被注册！'}, status=status.HTTP_400_BAD_REQUEST)

        if mobile == '':
            return Response({'msg': '请输入手机号码！'}, status=status.HTTP_400_BAD_REQUEST)
        return Response({'msg': '手机号码没问题。'}, status=status.HTTP_200_OK)


# 完善个人信息
class PerfectInformationAPIView(RetrieveUpdateAPIView):

    queryset = models.User.objects.all()
    serializer_class = serializers.PerfectInformationModelSerializer


# 手机验证码
class SMSAPIView(APIView):

    def get(self, request, mobile):

        redis_conn = get_redis_connection('sms_code')
        check_ret = redis_conn.get(f'mobile_{mobile}')

        if check_ret:
            return Response({'msg': '60秒内不允许再次点击发送验证码'}, status=status.HTTP_400_BAD_REQUEST)
        try:
            # 1. 生成6位随机验证码
            sms_code = "%06d" % random.randint(0, 999999)

            # 2. 将随机验证码保存到redis中
            redis_conn = get_redis_connection('sms_code')

            # 创建管道
            pipe = redis_conn.pipeline()

            # 开启管道
            pipe.multi()

            pipe.setex(f'sms_{mobile}', contants.SMS_EXPIRE_TIME, sms_code)

            # 3. 设置一个时间间隔的键值对
            pipe.setex(f'mobile_{mobile}', contants.SMS_INTERVAL_TIME, '_')

            # 统一一次执行
            pipe.execute()

            # 4. 调用SendMessage模块的方法将请求发送到容联云后台，将随机验证码发送给该手机号码
            # res = send_message(mobile, (sms_code, contants.SMS_EXPIRE_TIME // 60), '1')
            # if res.get('statusCode') == '000000':
            #     return Response({'msg': '短信发送成功'}, status=status.HTTP_200_OK)
            # logger.error(f'{mobile} 短信发送失败')
            # return Response({'msg': '短信发送失败'}, status=status.HTTP_400_BAD_REQUEST)
            send_sms1.delay(mobile, sms_code)
            return Response({'msg': '手机验证码已发送'})
        except:
            logger.error('服务器内部错误')
            return Response({'msg': '服务器内部错误'}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)


# 向qq邮箱发送验证码接口
class EmailVerifyAPIView(APIView):

    def get(self, request, pk):

        email = models.User.objects.get(pk=pk).email

        if email == '未填写':
            return Response({'msg': '未绑定邮箱！'}, status=status.HTTP_400_BAD_REQUEST)

        redis_conn = get_redis_connection('email_code')
        check_ret = redis_conn.get(f'email_{email}')

        # 30s内用户只能发送一次
        if check_ret:
            return Response({'msg': '操作频繁！'}, status=status.HTTP_400_BAD_REQUEST)

        # 生成验证码
        code = ''.join(random.sample(string.ascii_letters + string.digits, 4))

        # 发送邮件
        # send_mail的参数分别是:
        # 邮件标题，
        # 邮件内容，
        # 发件箱(settings.py中设置过的那个)，
        # 收件箱列表(可以发送给多个人),
        # 失败静默(若发送失败，报错提示我们)
        send_mail(
            '重置密码',
            '验证码：%s' % code,
            '1013659817@qq.com',
            [email],
            fail_silently=True,
        )
        # 2. 将随机验证码保存到redis中
        redis_conn = get_redis_connection('email_code')
        redis_conn.setex(f'email_code_{email}', contants.SMS_EXPIRE_TIME, code)

        # 3. 设置一个时间间隔的键值对
        redis_conn.setex(f'email_{email}', contants.SMS_INTERVAL_TIME, '_')
        return Response({'msg': '验证邮件成功发送！'}, status=status.HTTP_200_OK)


# 修改密码接口
class ResetPassword(UpdateAPIView):

    queryset = models.User.objects.all()
    serializer_class = serializers.ResetPasswordModelSerializer
